<!--
 * @Description:
 * @version:
 * @Author: 尹鹏孝
 * @Date: 2023-03-03 09:15:35
 * @LastEditors: 尹鹏孝
 * @LastEditTime: 2023-03-03 11:08:06
-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>类型</title>
</head>
<body>
<script>
    function Foo(){}
    Foo.prototype;
    console.log(Foo.prototype);

    var a = new Foo();
    console.log(Object.getPrototypeOf(a) === Foo.prototype);

    console.log(a.prototype)
    console.log(Foo.prototype);
    console.log(Object.getPrototypeOf(a))
    // 使用new调用一个函数发生构造函数调用时候，会自动执行以下四步骤操作
    // 1、创建一个全新对象
    // 2、创建这个对象的原型连接
    // 3、对这个新对象会绑定到函数的this
    // 4、如果函数没有返回其他对象，那么new表达式中的函数会自动返回这个新对象


    //更新的方法是使用Object.create方法。

    // 对象的prototype关联对象会产生原型继承.那么怎么生成原型继承？javascript的对象并不会产出真正意义的继承，只是通过prototype进行对象之间的关联。


    function FooB(){}
    var b = new FooB();
    // 是什么让人感觉FooB()是一个类，一是看到了new，也是用了FooB的构造方法，


    function FooC(){}
    FooC.prototype.constructor === FooC;
    var mip = new FooC();
    console.log(mip.constructor === FooC)


    function NothingSpecial(){
        console.log("don´t mind me")
    }

    var mind = new NothingSpecial()
    console.log(mind)
    // 带有new的函数调用是构造函数，但是NothingSpecial并不是构造函数

    function ForBiden(name){
        this.name = name;
    }

    ForBiden.prototype.myName = function(){
        console.log(this.name)
        return this.name;
    }

    var abs = new ForBiden("a");
    var bbs = new ForBiden("b");
    abs.myName();
    bbs.myName();


    function PDF(){}
    PDF.prototype={}
    var a1 = new PDF();
    a1.constructor===PDF;
    a1.constructor===Object;

    // a1没有constructor属性，所以他会委托[[Prototype]]链接上的PDF.prototype但是这个对象也没有.constructor属性所以会继续委托，这次委托链顶端的Object.prototype。这个对象有constructor属性，指向内置Object()函数


    function FooBif(){}
    FooBif.prototype = {};
    Object.defineProperty(Foo.prototype,"constructor",{
        enumerable:false,
        writable:true,
        configurable:true,
        value:FooBif
    });


    //原型继承
    function Ts(name){
        this.name=name;
    }
    Ts.prototype.myName = function(){
        console.log(this.name)
        return this.name;
    }

    function Bf(name,label){
        Ts.call(this,name);
        this.label = label;
    }

    Bf.prototype = Object.create(Ts.prototype);


    Bf.prototype.myLabel = function(){
        console.log(this.label)
        return this.label;
    }

    var mb = new Bf("a,","obj a");
    mb.myName();
    mb.myLabel();

    // 这段代码的核心是Bf.prototype = Object.create(Ts.prototype)调用Object.create会凭空创建一个新对象，并且吧对象内部prototype关联到指定对象。

    // __proto__的实现机制

    Object.defineProperty(Object.prototype,"__proto__",{
        get:function(){
            return Object.getPrototypeOf(this)
        },
        set:function(o){
            Object.setPrototypeOf(this,o);
            return o;
        }
    })

    //对象关联-------原型链

    // Object.create是实现对象关联的方法，对象关联本质还是调用了对象的prototype进行查找对象属性名，通过Object.create 可以修改这种关联而且不产生副作用
    //手动实现Object.create的简洁版,闭包模式实现的只是通过Prototype进行了绑定给定参数返回一个new 创建的对象。
    if(Object.create){
        Object.create = function(o){
            function F(){}
            F.prototype=o;
            return new F();
        }
    }



    var doObject={
        cool:function(){
            console.log("cool");
        }
    };

    var nB = Object.create(doObject);
    nB.doCool=function(){
        this.cool();
    }

    nB.cool();


</script>
</body>
</html>